//
// Created by 25429 on 2021/2/3.
//

#ifndef SIRIUS3_COMMON_STRUCT_H
#define SIRIUS3_COMMON_STRUCT_H

#include <utility>

#include "common_define.h"

enum SiriusQueueType {
    // 市场
    QUEUE_EVENT_MARKET_CLOSE = 0,
    QUEUE_EVENT_MARKET_OPEN,
    // 配置
    QUEUE_EVENT_CONFIG_CHANGE,
    // 策略
    QUEUE_STRATEGY_INIT,
    // 行情
    QUEUE_MD_INIT,
    QUEUE_MD_L2_MKT,
    // 交易
    QUEUE_TRADE_BALANCES,
    QUEUE_TRADE_BALANCES_RSP,
    QUEUE_TRADE_HOLDING,
    QUEUE_TRADE_HOLDING_RSP,
    QUEUE_TRADE_HOLDING_UPDATE,
    QUEUE_TRADE_ORDERS,
    QUEUE_TRADE_DEALS,
    QUEUE_TRADE_ORDER_INSERT,
    QUEUE_TRADE_ORDER_REJECTED,
    QUEUE_TRADE_ORDER_RECEIVED,
    QUEUE_TRADE_ORDER_UPDATE,
    QUEUE_TRADE_ORDER_DEAL,
    QUEUE_TRADE_ORDER_CANCEL,
    QUEUE_TRADE_ORDER_CANCEL_RECEIVED,
    QUEUE_TRADE_ORDER_CANCEL_REJECTED
};

enum TASK_TYPE {
    BUY_TASK = 0,
    SELL_TASK
};

enum LIMIT_UP_PHASE {
    WAIT_CONDITION = 0,

    STOP,// 停止
    ABANDON,// 废弃
    WAIT_SOME_TIME,// 等待某个时间
};

struct TimePassField {
    int diff = 0;
    int tag{};

    TimePassField() = default;

    TimePassField(int diff_in, int tag_in) : diff(diff_in),
                                             tag(tag_in) {};
};

struct SiriusTradeReqOrderInsertExField {
    string symbol{};
    int direction{}; // buy/sell
    int volume{0};
    int price{0};
    int16 system_order_no{};

// 行情的原点
    int64_t original_point = 0;

    // 撤单的时候有用
    bool need_cancel = false;
    int64 order_id = -1;
    int market = -1;

    SiriusTradeReqOrderInsertExField() = default;

    SiriusTradeReqOrderInsertExField(string
                                     symbol_in,
                                     int direction_in,
                                     int volume_in,
                                     int price_in,
                                     int16
                                     system_order_no_in,
                                     int64_t original_point_in
    ) :

            symbol(std::move(symbol_in)),
            direction(direction_in),
            volume(volume_in),
            price(price_in),
            system_order_no(system_order_no_in),
            original_point(original_point_in) {

    }

    SiriusTradeReqOrderInsertExField(int16
                                     system_order_no_in,
                                     int64_t original_point_in
    ) :

            system_order_no(system_order_no_in),
            original_point(original_point_in) {

    }

};

struct SiriusTradeReqOrderInsertField {
    string symbol{};
    int direction{}; // buy/sell
    int volume{0};
    int price{0};
    int16 system_order_no{};

    // 行情的原点
    int64_t original_point = 0;

    // 撤单的时候有用
    bool need_cancel = false;
    int64 order_id = -1;
    int market = -1;

    SiriusTradeReqOrderInsertField() = default;

    SiriusTradeReqOrderInsertField(string symbol_in,
                                   int direction_in,
                                   int volume_in,
                                   int price_in,
                                   int16 system_order_no_in,
                                   int64_t original_point_in) : symbol(std::move(symbol_in)),
                                                                direction(direction_in),
                                                                volume(volume_in),
                                                                price(price_in),
                                                                system_order_no(system_order_no_in),
                                                                original_point(original_point_in) {

    }

    SiriusTradeReqOrderInsertField(int16 system_order_no_in,
                                   int64_t original_point_in) :
            system_order_no(system_order_no_in),
            original_point(original_point_in) {

    }
};

struct SiriusTradeRspOrderRejectedField {
    int error_id{};
    int16 system_order_no = 0; // 系统编号

    SiriusTradeRspOrderRejectedField() = default;

    SiriusTradeRspOrderRejectedField(int16 system_order_no_in, int error_id_in) : system_order_no(system_order_no_in),
                                                                                  error_id(error_id_in) {}
};

struct SiriusTradeRspOrderReceivedField {
    int16 system_order_no = 0; // 系统编号
    int64 order_id = -1;

    SiriusTradeRspOrderReceivedField() = default;

    SiriusTradeRspOrderReceivedField(int16 system_order_no_in, int64 order_id_in) : system_order_no(system_order_no_in),
                                                                                    order_id(order_id_in) {}
};

struct SiriusTradeReqOrderCancelField {
    int16 system_order_no = 0;
    // 行情的原点
    int64_t original_point = 0;

    SiriusTradeReqOrderCancelField() = default;

    explicit SiriusTradeReqOrderCancelField(int16 system_order_no_in, int64_t original_point_in) : system_order_no(
            system_order_no_in), original_point(original_point_in) {}
};

struct SiriusTradeRspOrderCancelField {
    int16 system_order_no = 0; // 系统编号
    SiriusTradeRspOrderCancelField() = default;

    explicit SiriusTradeRspOrderCancelField(int16 system_order_no_in) : system_order_no(
            system_order_no_in) {}
};

struct SiriusTradeRspOrderCancelReceivedField {
    int16 system_order_no = 0; // 系统编号
    SiriusTradeRspOrderCancelReceivedField() = default;

    explicit SiriusTradeRspOrderCancelReceivedField(int16 system_order_no_in) : system_order_no(
            system_order_no_in) {}
};

struct SiriusTradeRspOrderCancelRejectedField {
    int16 system_order_no = 0; // 系统编号
    int error_id{0};    // 错误码
    SiriusTradeRspOrderCancelRejectedField() = default;

    SiriusTradeRspOrderCancelRejectedField(int16 system_order_no_in, int error_id_in) : system_order_no(
            system_order_no_in), error_id(error_id_in) {}
};

struct SiriusTradeRspBalanceField {
    int64 currentTotalBal;
    /** 当前可用余额 */
    int64 currentAvailableBal;
    /** 当前可取余额 */
    int64 currentDrawableBal;
};

struct SiriusTradeRspHoldingField {
    string symbol{};
    int available_volume{};// 可用数量
    int history_volume{};// 昨日数量
    int64 sumHld;// 总持仓
    int64 costPrice;

    SiriusTradeRspHoldingField()
    = default;

    SiriusTradeRspHoldingField(const string &symbol_t, int available_volume_t,
                               int history_volume_t) {
        symbol = symbol_t;
        available_volume = available_volume_t;
        history_volume = history_volume_t;
    }
};

struct SiriusTradeRspOrderField {
    int16 system_order_no = 0; // 系统编号
    int64 order_id{};// 委托编号

    int volume{};// 报单数量
    int price{};// 挂单价格
    int deal_volume{};// 成交数量
    int64 deal_amt{};// 成交金额
    int order_status{};// 委托状态

    SiriusTradeRspOrderField() = default;

    SiriusTradeRspOrderField(int16 system_order_no_in, int64 order_id_in, int volume_in, int price_in,
                             int deal_volume_in, int64 deal_amt_in, int order_status_in) :
            system_order_no(system_order_no_in), order_id(order_id_in), volume(volume_in), price(price_in),
            deal_volume(deal_volume_in), deal_amt(deal_amt_in), order_status(order_status_in) {};
};

struct SiriusTradeRspOrderDealField {
    int16 system_order_no = 0; // 系统编号
    int64 order_id = -1;
    int deal_volume{};// 成交数量
    int deal_price{};// 成交金额

    SiriusTradeRspOrderDealField() = default;

    SiriusTradeRspOrderDealField(int16 system_order_no_in, int64 order_id_in, int deal_volume_in, int deal_price_in) :
            system_order_no(system_order_no_in), order_id(order_id_in), deal_volume(deal_volume_in),
            deal_price(deal_price_in) {};
};

struct SiriusQueueFastField {
    SiriusQueueType type{};
    SiriusTradeReqOrderInsertField order{};

    SiriusQueueFastField() = default;

    explicit SiriusQueueFastField(SiriusQueueType type_in, SiriusTradeReqOrderInsertField f) : type(type_in),
                                                                                               order(std::move(f)) {
    }
};

//struct SiriusQueueFastField {
//    SiriusQueueType type{};
//    SiriusTradeReqOrderInsertField order{};
//
//    SiriusQueueFastField() = default;
//
//    explicit SiriusQueueFastField(SiriusTradeReqOrderInsertField f) : type(QUEUE_TRADE_ORDER_INSERT),
//                                                                      order(std::move(f)) {
//    }
//};

struct SiriusQueueField {
    SiriusQueueType type{};
    SiriusTradeRspHoldingField trade_holding_update{};
    SiriusTradeRspOrderField trade_order_update{};
    SiriusTradeRspOrderDealField trade_order_deal{};
    SiriusTradeRspOrderRejectedField trade_order_rejected{};
    SiriusTradeRspOrderReceivedField trade_order_received{};
    SiriusTradeRspOrderCancelReceivedField trade_order_cancel_received{};
    SiriusTradeRspOrderCancelRejectedField trade_order_cancel_rejected{};
    vector<SiriusTradeRspHoldingField> trade_holdings{};
    SiriusTradeRspBalanceField trade_balance{};

    SiriusQueueField() = default;

    explicit SiriusQueueField(SiriusQueueType type_in) : type(type_in) {};

    explicit SiriusQueueField(vector<SiriusTradeRspHoldingField> f) : type(QUEUE_TRADE_HOLDING_RSP),
                                                                      trade_holdings(std::move(f)) {
    }

    explicit SiriusQueueField(SiriusTradeRspBalanceField f) : type(QUEUE_TRADE_BALANCES_RSP),
                                                              trade_balance(f) {
    }

    explicit SiriusQueueField(SiriusTradeRspOrderCancelReceivedField f) : type(
            SiriusQueueType::QUEUE_TRADE_ORDER_CANCEL_RECEIVED), trade_order_cancel_received(f) {
    }

    explicit SiriusQueueField(SiriusTradeRspOrderCancelRejectedField f) : type(
            SiriusQueueType::QUEUE_TRADE_ORDER_CANCEL_REJECTED), trade_order_cancel_rejected(f) {
    }

    explicit SiriusQueueField(SiriusTradeRspOrderReceivedField f) : type(
            SiriusQueueType::QUEUE_TRADE_ORDER_RECEIVED), trade_order_received(f) {
    }

    explicit SiriusQueueField(SiriusTradeRspOrderRejectedField f) : type(
            SiriusQueueType::QUEUE_TRADE_ORDER_REJECTED), trade_order_rejected(f) {
    }

    explicit SiriusQueueField(SiriusTradeRspOrderField f) : type(SiriusQueueType::QUEUE_TRADE_ORDER_UPDATE),
                                                            trade_order_update(f) {
    }

    explicit SiriusQueueField(SiriusTradeRspOrderDealField f) : type(SiriusQueueType::QUEUE_TRADE_ORDER_DEAL),
                                                                trade_order_deal(f) {
    }

    explicit SiriusQueueField(SiriusTradeRspHoldingField f) : type(SiriusQueueType::QUEUE_TRADE_HOLDING_UPDATE),
                                                              trade_holding_update(std::move(f)) {
    }
};

struct l2_mkt {
    int32 time = 0;
    int32 deal = 0;
    std::string security;
    std::map<int32, int64> buy_levels{};
    std::map<int32, int64> sell_levels{};
    double total_deal = 0;
    int32 up_limit_of_pub = 0;

    l2_mkt() = default;
};

struct SiriusConfigStockField {
    string symbol{};
    int limit_up_price = 1;// 涨停价
    int limit_down_price = 1;// 跌停价
    int pre_close = 1;
    int pre_close_add_10_percent = 1;
    int up_limit_of_pub_sh = 1;// 上海行情发布价格限制
    int up_limit_of_pub_sz = 1;// 深圳行情发布价格限制
    int64 circ_mv = 1;// 流通市值
    int classify = 0;// 板块分类
    double max_block_money = 0;// 最大封板
    int max_block_money_time = 0;// 最大封板时间

    SiriusConfigStockField()
    = default;

    bool operator==(SiriusConfigStockField &f) const {
        return f.symbol == symbol;
    }

    explicit SiriusConfigStockField(const string &symbol_in, int limit_up_price_in, int limit_down_price_in,
                                    int up_limit_of_pub_sh_in, int up_limit_of_pub_sz_in,
                                    int64 circ_mv_in, int classify_in) {
        symbol = symbol_in;
        limit_up_price = limit_up_price_in;
        limit_down_price = limit_down_price_in;
        pre_close = int((limit_up_price + limit_down_price) * 0.5);
        pre_close_add_10_percent = pre_close * 1.1;
        up_limit_of_pub_sh = up_limit_of_pub_sh_in;
        up_limit_of_pub_sz = up_limit_of_pub_sz_in;
        circ_mv = circ_mv_in;
        classify = classify_in;
    }

    explicit SiriusConfigStockField(const string &symbol_in) {
        symbol = symbol_in;
    }
};

struct SiriusMDRspMarketMiniField {
    string symbol{};
    int time = 0;
    int last_price = 0;
    double total_deal = 0;
    int bid1_price = 0;
    int bid1_volume = 0;
    int offer1_price = 0;
    int offer1_volume = 0;

    // 行情的原点
    int64_t original_point = 0;

    SiriusMDRspMarketMiniField() = default;

    SiriusMDRspMarketMiniField(string symbol_in, int time_in, int last_price_in, double total_deal_in,
                               int bid1_price_in, int bid1_volume_in,
                               int64_t original_point_in) : symbol(std::move(symbol_in)), time(time_in),
                                                            last_price(last_price_in),
                                                            total_deal(total_deal_in),
                                                            bid1_price(bid1_price_in),
                                                            bid1_volume(bid1_volume_in),
                                                            original_point(original_point_in) {

    }

    SiriusMDRspMarketMiniField(string symbol_in, int time_in, int last_price_in, double total_deal_in,
                               int64_t original_point_in) : symbol(std::move(symbol_in)),
                                                            time(time_in),
                                                            last_price(last_price_in),
                                                            total_deal(total_deal_in),
                                                            original_point(original_point_in) {}
};

struct SiriusMDRspMarketField {
    string symbol{};
    int time = 0;
    int last_price = 0;
    double total_deal = 0;
    int bid1_price = 0;
    int bid1_volume = 0;
    int offer1_price = 0;
    int offer1_volume = 0;

    // 行情的原点
    int64_t original_point = 0;

    SiriusMDRspMarketField() = default;

    SiriusMDRspMarketField(string symbol_in, int time_in, int last_price_in, double total_deal_in,
                           int bid1_price_in, int bid1_volume_in) : symbol(std::move(symbol_in)), time(time_in),
                                                                    last_price(last_price_in),
                                                                    total_deal(total_deal_in),
                                                                    bid1_price(bid1_price_in),
                                                                    bid1_volume(bid1_volume_in) {

    }

    SiriusMDRspMarketField(string symbol_in, int time_in, int last_price_in, double total_deal_in,
                           int64_t original_point_in) : symbol(std::move(symbol_in)), time(time_in),
                                                        last_price(last_price_in),
                                                        total_deal(total_deal_in),
                                                        original_point(original_point_in) {

    }

    SiriusMDRspMarketField(const SiriusMDRspMarketMiniField &mkt) : symbol(mkt.symbol), time(mkt.time),
                                                                    last_price(mkt.last_price),
                                                                    total_deal(mkt.total_deal),
                                                                    bid1_price(mkt.bid1_price),
                                                                    bid1_volume(mkt.bid1_volume),
                                                                    original_point(mkt.original_point) {

    }
};


#endif //SIRIUS3_COMMON_STRUCT_H
